﻿using Kinlo.MESDocking;
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using UIWindows.Attributes;
using UIWindows.Commands;
using UIWindows.Enums;
using UIWindows.GlobalStatics;
using UIWindows.Tools.Converter;
using UIWindows.Tools.Helper;
using UIWindows.ViewModels.Dialogs;
using UIWindows.Views.Dialogs;
using XingLucifer.IBase.Enums;

namespace UIWindows.ViewModels
{
    public class ParameterConfigurationViewModel : XingLucifer.IBase.IViewStatus
    {
        private DisplayItemsStatic _displayItems;
        #region 容器
        public object FunctionEnable { get; set; }
        public object CollectionItemsParameterPanel { get; set; }
        public object MESPanel { get; set; }
        public object RangePanel { get; set; }
        public object RunPanel { get; set; }
        #endregion
        #region 参数
        public Models.ParameterModels.CollectionItemsParameterModel CollectionItemsParameter { get; set; }
        public Models.ParameterModels.DecideParameterModel DecideParameter { get; set; }
        public Models.ParameterModels.MESParameterModel MESParameter { get; set; }
        public Models.ParameterModels.RangeParameterModel RangeParameter { get; set; }
        public Models.ParameterModels.RunParameterModel RunParameter { get; set; }
        public DeviceConfigStatic DeviceConfig { get; set; }
        #endregion
        public UserConfigStatic UserConfig { get; set; }
        public ParameterStatic Parameter { get; set; }
        public TemporaryStatic Temporary { get; set; }
        public ParameterConfigurationViewModel(
            UserConfigStatic userConfig,
            ParameterStatic parameter,
            TemporaryStatic temporary,
            DisplayItemsStatic displayItems,
            DeviceConfigStatic deviceConfig
            )
        {
            DeviceConfig = deviceConfig;
            UserConfig = userConfig;
            Parameter = parameter;
            Temporary = temporary;
            _displayItems = displayItems;
            //parameter.DecideParameter.EnableReinvestmentMode = false;
            parameter.DecideParameter.EnableEmptyRun = false;
            parameter.DecideParameter.EnableMES = true;
            //parameter.DecideParameter.EnableVariableInjection = true;
            var serviceList = Temporary.LinkList.FirstOrDefault(x => x.ServiceName == "MES状态");
            if (serviceList != null) { serviceList.Status = Parameter.DecideParameter.EnableMES; }
            #region 初始化
            RunParameter = new Models.ParameterModels.RunParameterModel();
            DecideParameter = new Models.ParameterModels.DecideParameterModel();
            MESParameter = new Models.ParameterModels.MESParameterModel();
            RangeParameter = new Models.ParameterModels.RangeParameterModel();
            CollectionItemsParameter = new Models.ParameterModels.CollectionItemsParameterModel();
            #endregion
            var roleControl = new RoleControlConverter();
            #region 采集项参数
            StackPanel collectionItemsPanel = new StackPanel();
            collectionItemsPanel.Orientation = Orientation.Vertical;
            CreateChildren(collectionItemsPanel, CollectionItemsParameter, temporary, "NotificationRefresh", roleControl);
            CollectionItemsParameterPanel = collectionItemsPanel;
            #endregion

            #region 功能启用
            StackPanel functionPanel = new StackPanel();
            functionPanel.Orientation = Orientation.Vertical;
            CreateChildrenFunction(functionPanel, DecideParameter, temporary, "NotificationRefresh", roleControl);
            FunctionEnable = functionPanel;
            #endregion

            #region MES
            StackPanel mesPanel = new StackPanel();
            mesPanel.Orientation = Orientation.Vertical;
            CreateChildrenUrl(mesPanel, MESParameter, temporary, "NotificationRefresh", roleControl);
            MESPanel = mesPanel;
            #endregion

            #region 范围
            StackPanel rangePanel = new StackPanel();
            rangePanel.Orientation = Orientation.Vertical;
            CreateChildrenRange(rangePanel, RangeParameter, temporary, "NotificationRefresh", roleControl);
            RangePanel = rangePanel;
            #endregion

            #region 运行参数
            StackPanel runPanel = new StackPanel();
            runPanel.Orientation = Orientation.Vertical;
            CreateMiscellaneousChildrenRange(runPanel, RunParameter, temporary, "NotificationRefresh", roleControl);
            RunPanel = runPanel;
            #endregion
            _displayItems.SaveRoleInit();
            SetInjectionVolume();
        }

        #region 工艺参数
        private void CreateChildren(Panel panel, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            var property = obj.GetType().GetProperties();
            for (int i = 0; i < property.Length;)
            {
                var attr = property[i].GetCustomAttribute<UIMarkAttribute>();
                if (attr == null) { i++; continue; }
                panel.Children.Add(CreatePanel(property, ref i, property.Length, attr.LayerNumber, obj, obj_converter, bingd_converter, converter));
            }
        }

        private Grid CreatePanel(PropertyInfo[] properties, ref int index, int indexMax, int layer, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            Grid grid = new Grid();
            grid.Height = 40;
            ColumnDefinitionCollection columns = grid.ColumnDefinitions;
            int width = layer < 3 ? 100 : 50;
            for (int i = 0; i < layer; i++)
            {
                columns.Add(new ColumnDefinition()
                {
                    Width = new GridLength((layer == 3) && (i == 0) ? 80 : width),
                });
                columns.Add(new ColumnDefinition()
                {
                    Width = new GridLength(layer == 1 ? 300 : layer == 3 ? 80 : 100),
                });
            }
            return CreateContent(properties, 0, ref index, grid, indexMax, width, layer == 1 ? 300 : layer == 3 ? 80 : 100, layer, obj, obj_converter, bingd_converter, converter);
        }

        private Grid CreateContent(PropertyInfo[] properties, int column, ref int index, Grid grid, int indexMax, int blockWidth, int width, int layer,
            object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            if (layer == 0 || index >= indexMax) { return grid; }
            var attribute = properties[index].GetCustomAttribute<UIMarkAttribute>();
            if (attribute != null)
            {
                grid.Children.Add(GetTextBlock(attribute, column * 2, blockWidth));
                grid.Children.Add(GetContent(attribute, properties[index], column * 2 + 1, width, obj, obj_converter, bingd_converter, converter));
                layer -= 1;
                column++;
            }
            index++;
            return CreateContent(properties, column, ref index, grid, indexMax, blockWidth, width, layer, obj, obj_converter, bingd_converter, converter);
        }

        private FrameworkElement GetContent(UIMarkAttribute attribute, PropertyInfo propertyInfo, int column, int width,
            object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            if (propertyInfo.PropertyType.BaseType.Name == "Collection`1")
            {
                return GetCollection(propertyInfo.Name, column, obj, attribute, obj_converter, bingd_converter, converter);
            }
            if (propertyInfo.PropertyType.BaseType.Name == "Enum")
            {
                return GetComboBox(propertyInfo.Name, column, attribute.CollectionName, attribute.MyExpression, obj, attribute, obj_converter, bingd_converter, converter);
            }
            switch (propertyInfo.PropertyType.Name)
            {
                case "Byte":
                case "String":
                case "Double":
                case "Int32":
                case "UInt32":
                    return GetTextBox(propertyInfo.Name, attribute.Suffix, column, obj, attribute, obj_converter, bingd_converter, converter);
            }
            return default;
        }

        private TextBlock GetTextBlock(UIMarkAttribute attribute, int column, int width)
        {
            TextBlock textBlock = new TextBlock();
            textBlock.Text = attribute.Name;
            textBlock.HorizontalAlignment = HorizontalAlignment.Right;
            textBlock.VerticalAlignment = VerticalAlignment.Center;
            textBlock.SetValue(Grid.ColumnProperty, column);
            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            textBlock.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            if (!_displayItems.RoleInit.Any(x => x.RoleName == attribute.Name))
            {
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "采集项参数",
                    Authority = Enums.AuthorityTypes.操作员,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "采集项参数",
                    Authority = Enums.AuthorityTypes.工艺,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "采集项参数",
                    Authority = Enums.AuthorityTypes.设备,
                    RoleName = attribute.Name,
                });
            }
            return textBlock;
        }

        private TextBox GetTextBox(string bingd, string suffix, int column, object obj,
            UIMarkAttribute attribute, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            TextBox textBox = new TextBox();
            textBox.VerticalAlignment = VerticalAlignment.Center;
            textBox.Margin = new Thickness(5);
            textBox.SetValue(Grid.ColumnProperty, column);
            textBox.SetValue(TextFieldAssist.SuffixTextProperty, suffix);
            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            textBox.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            Binding binding = new Binding();
            binding.Source = obj;
            binding.Path = new PropertyPath(bingd);
            binding.Mode = BindingMode.TwoWay;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding);

            Binding bindingConverter = new Binding();
            bindingConverter.Source = obj_converter;
            bindingConverter.Path = new PropertyPath(bingd_converter);
            bindingConverter.Mode = BindingMode.TwoWay;
            bindingConverter.Converter = converter;
            bindingConverter.ConverterParameter = attribute.Name;
            bindingConverter.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(textBox, TextBox.IsEnabledProperty, bindingConverter);
            return textBox;
        }

        private ComboBox GetComboBox(string bingd, int column, Type type, string[] expression, object obj,
            UIMarkAttribute attribute, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            ComboBox comboBox = new ComboBox();
            comboBox.SetValue(Grid.ColumnProperty, column);
            if (expression != null)
            {
                System.Linq.Expressions.Expression<Func<string, bool>> condition = x => true;
                if (expression.Length > 1)
                {
                    if (!string.IsNullOrEmpty(expression[0]) && !string.IsNullOrEmpty(expression[1]))
                    {
                        condition = x => !x.Contains(expression[0]);
                        System.Linq.Expressions.Expression<Func<string, bool>> classExp = s => s.Contains(expression[1]);
                        var invokedExpr = System.Linq.Expressions.Expression.Invoke(classExp, condition.Parameters.Cast<System.Linq.Expressions.Expression>());
                        condition = System.Linq.Expressions.Expression.Lambda<Func<string, bool>>(System.Linq.Expressions.Expression.AndAlso(condition.Body, invokedExpr), condition.Parameters);
                    }
                    if (string.IsNullOrEmpty(expression[0]) && !string.IsNullOrEmpty(expression[1]))
                    {
                        condition = x => x.Contains(expression[1]);
                    }
                    if (!string.IsNullOrEmpty(expression[0]) && string.IsNullOrEmpty(expression[1]))
                    {
                        condition = x => !x.Contains(expression[0]);
                    }
                }
                for (int i = 2; i < expression.Length; i++)
                {
                    string str = expression[i];
                    System.Linq.Expressions.Expression<Func<string, bool>> classExp = s => s != str;
                    var invokedExpr = System.Linq.Expressions.Expression.Invoke(classExp, condition.Parameters.Cast<System.Linq.Expressions.Expression>());
                    condition = System.Linq.Expressions.Expression.Lambda<Func<string, bool>>(System.Linq.Expressions.Expression.AndAlso(condition.Body, invokedExpr), condition.Parameters);
                }
                var where = condition.Compile();
                comboBox.ItemsSource = type.GetEnumNames().Where(where);
            }
            else
            {
                comboBox.ItemsSource = type.GetEnumNames();
            }
            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            comboBox.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            comboBox.VerticalAlignment = VerticalAlignment.Center;
            comboBox.Width = 90;
            comboBox.Margin = new Thickness(5);
            Binding binding = new Binding();
            binding.Source = obj;
            binding.Path = new PropertyPath(bingd);
            binding.Mode = BindingMode.TwoWay;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(comboBox, ComboBox.TextProperty, binding);

            Binding bindingConverter = new Binding();
            bindingConverter.Source = obj_converter;
            bindingConverter.Path = new PropertyPath(bingd_converter);
            bindingConverter.Mode = BindingMode.TwoWay;
            bindingConverter.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            bindingConverter.ConverterParameter = attribute.Name;
            bindingConverter.Converter = converter;
            BindingOperations.SetBinding(comboBox, TextBox.IsEnabledProperty, bindingConverter);
            return comboBox;
        }

        private ComboBox GetCollection(string bingd, int column, object obj,
    UIMarkAttribute attribute, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            ComboBox comboBox = new ComboBox();
            comboBox.SetValue(Grid.ColumnProperty, column);

            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            comboBox.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            comboBox.VerticalAlignment = VerticalAlignment.Center;
            comboBox.Margin = new Thickness(5);
            Binding bindingItem = new Binding();
            bindingItem.Source = obj;
            bindingItem.Path = new PropertyPath(bingd);
            bindingItem.Mode = BindingMode.TwoWay;
            bindingItem.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(comboBox, ComboBox.ItemsSourceProperty, bindingItem);

            int length = bingd.Length;
            Binding binding = new Binding();
            binding.Source = obj;
            binding.Path = new PropertyPath(bingd.Substring(0, length - 11));
            binding.Mode = BindingMode.TwoWay;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(comboBox, ComboBox.TextProperty, binding);
            BindingOperations.SetBinding(comboBox, ComboBox.SelectedItemProperty, binding);

            Binding bindingConverter = new Binding();
            bindingConverter.Source = obj_converter;
            bindingConverter.Path = new PropertyPath(bingd_converter);
            bindingConverter.Mode = BindingMode.TwoWay;
            bindingConverter.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            bindingConverter.ConverterParameter = attribute.Name;
            bindingConverter.Converter = converter;
            BindingOperations.SetBinding(comboBox, TextBox.IsEnabledProperty, bindingConverter);
            return comboBox;
        }
        #endregion

        #region Mes Url
        private void CreateChildrenUrl(Panel panel, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            var property = obj.GetType().GetProperties();
            for (int i = 0; i < property.Length;)
            {
                var attr = property[i].GetCustomAttribute<UIMarkAttribute>();
                if (attr == null) { i++; continue; }
                panel.Children.Add(CreatePanelMES(property, ref i, obj, obj_converter, bingd_converter, converter));
            }
        }
        private Grid CreatePanelMES(PropertyInfo[] properties, ref int index, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            Grid grid = new Grid();
            grid.Height = 40;
            grid.Width = 850;
            ColumnDefinitionCollection columns = grid.ColumnDefinitions;
            columns.Add(new ColumnDefinition()
            {
                Width = new GridLength(120),
            });
            columns.Add(new ColumnDefinition()
            {
                //Width = new GridLength(1, GridUnitType.Star),
                Width = new GridLength(1, GridUnitType.Star),
            });
            columns.Add(new ColumnDefinition()
            {
                Width = new GridLength(120),
            });
            columns.Add(new ColumnDefinition()
            {
                Width = new GridLength(120),
            });
            return CreateContentMES(properties, 0, ref index, grid, obj, obj_converter, bingd_converter, converter);
        }

        private Grid CreateContentMES(PropertyInfo[] properties, int column, ref int index, Grid grid,
            object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            if (column == 4) { return grid; }
            var attribute = properties[index].GetCustomAttribute<UIMarkAttribute>();
            if (attribute != null && column > 1)
            {
                grid.Children.Add(GetTextBoxMES(properties[index].Name, column, obj, attribute, obj_converter, bingd_converter, converter));
                column++;
            }
            if (attribute != null && column < 2)
            {
                grid.Children.Add(GetTextBlockMES(attribute, column));
                grid.Children.Add(GetTextBoxMES(properties[index].Name, column + 1, obj, attribute, obj_converter, bingd_converter, converter));
                column += 2;
            }
            index++;
            return CreateContentMES(properties, column, ref index, grid, obj, obj_converter, bingd_converter, converter);
        }

        private TextBox GetTextBoxMES(string bingd, int column, object obj,
            UIMarkAttribute attribute, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            TextBox textBox = new TextBox();
            textBox.VerticalAlignment = VerticalAlignment.Center;
            textBox.Margin = new Thickness(5);
            textBox.SetValue(Grid.ColumnProperty, column);
            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            textBox.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            Binding binding = new Binding();
            binding.Source = obj;
            binding.Path = new PropertyPath(bingd);
            binding.Mode = BindingMode.TwoWay;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding);

            Binding bindingConverter = new Binding();
            bindingConverter.Source = obj_converter;
            bindingConverter.Path = new PropertyPath(bingd_converter);
            bindingConverter.Mode = BindingMode.TwoWay;
            bindingConverter.Converter = converter;
            bindingConverter.ConverterParameter = attribute.Name;
            bindingConverter.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(textBox, TextBox.IsEnabledProperty, bindingConverter);

            if (!_displayItems.RoleInit.Any(x => x.RoleName == attribute.Name))
            {
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "MES",
                    Authority = Enums.AuthorityTypes.操作员,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "MES",
                    Authority = Enums.AuthorityTypes.工艺,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "MES",
                    Authority = Enums.AuthorityTypes.设备,
                    RoleName = attribute.Name,
                });
            }
            return textBox;
        }

        private TextBlock GetTextBlockMES(UIMarkAttribute attribute, int column)
        {
            TextBlock textBlock = new TextBlock();
            textBlock.Text = attribute.Name;
            textBlock.HorizontalAlignment = HorizontalAlignment.Center;
            textBlock.VerticalAlignment = VerticalAlignment.Center;
            textBlock.SetValue(Grid.ColumnProperty, column);
            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            textBlock.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            return textBlock;
        }
        #endregion

        #region 功能启用
        private void CreateChildrenFunction(Panel panel, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            var property = obj.GetType().GetProperties();
            for (int i = 0; i < property.Length;)
            {
                var attr = property[i].GetCustomAttribute<UIMarkAttribute>();
                if (attr == null) { i++; continue; }
                panel.Children.Add(CreatePanelFunction(property, ref i, property.Length, attr.LayerNumber, obj, obj_converter, bingd_converter, converter));
            }
        }
        private Grid CreatePanelFunction(PropertyInfo[] properties, ref int index, int indexMax, int layer, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            Grid grid = new Grid();
            grid.Height = 40;
            ColumnDefinitionCollection columns = grid.ColumnDefinitions;
            int width = layer < 3 ? 100 : 50;
            for (int i = 0; i < layer; i++)
            {
                columns.Add(new ColumnDefinition()
                {
                    Width = new GridLength((layer == 3) && (i == 0) ? 80 : width),
                });
                columns.Add(new ColumnDefinition()
                {
                    Width = new GridLength(layer == 1 ? 300 : layer == 3 ? 80 : 100),
                });
            }
            return CreateContentFunction(properties, 0, ref index, grid, indexMax, width, layer == 1 ? 300 : layer == 3 ? 80 : 100, layer, obj, obj_converter, bingd_converter, converter);
        }
        private Grid CreateContentFunction(PropertyInfo[] properties, int column, ref int index, Grid grid, int indexMax,
            int blockWidth, int width, int layer,
            object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            if (layer == 0 || index >= indexMax) { return grid; }
            var attribute = properties[index].GetCustomAttribute<UIMarkAttribute>();
            if (attribute != null)
            {
                grid.Children.Add(GetTextBlockFunction(attribute, column * 2 + 1, blockWidth));
                grid.Children.Add(GetCheckBox(properties[index].Name, column * 2, attribute, obj, obj_converter, bingd_converter, converter));
                layer -= 1;
                column++;
            }
            index++;
            return CreateContentFunction(properties, column, ref index, grid, indexMax, blockWidth, width, layer, obj, obj_converter, bingd_converter, converter);
        }

        private TextBlock GetTextBlockFunction(UIMarkAttribute attribute, int column, int width)
        {
            TextBlock textBlock = new TextBlock();
            textBlock.Text = attribute.Name;
            textBlock.HorizontalAlignment = HorizontalAlignment.Left;
            textBlock.VerticalAlignment = VerticalAlignment.Center;
            textBlock.SetValue(Grid.ColumnProperty, column);
            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            textBlock.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            if (!_displayItems.RoleInit.Any(x => x.RoleName == attribute.Name))
            {
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "功能启用",
                    Authority = Enums.AuthorityTypes.操作员,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "功能启用",
                    Authority = Enums.AuthorityTypes.工艺,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "功能启用",
                    Authority = Enums.AuthorityTypes.设备,
                    RoleName = attribute.Name,
                });
            }
            return textBlock;
        }

        private CheckBox GetCheckBox(string bingd, int column, UIMarkAttribute attribute, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            CheckBox checkBox = new CheckBox();
            checkBox.VerticalAlignment = VerticalAlignment.Center;
            checkBox.HorizontalAlignment = HorizontalAlignment.Center;
            checkBox.Margin = new Thickness(5);
            checkBox.SetValue(Grid.ColumnProperty, column);
            Binding binding = new Binding();
            binding.Source = obj;
            binding.Path = new PropertyPath(bingd);
            binding.Mode = BindingMode.TwoWay;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(checkBox, CheckBox.IsCheckedProperty, binding);

            Binding bindingConverter = new Binding();
            bindingConverter.Source = obj_converter;
            bindingConverter.Path = new PropertyPath(bingd_converter);
            bindingConverter.Mode = BindingMode.TwoWay;
            bindingConverter.Converter = converter;
            bindingConverter.ConverterParameter = attribute.Name;
            bindingConverter.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(checkBox, TextBox.IsEnabledProperty, bindingConverter);
            return checkBox;
        }
        #endregion

        #region 工艺范围
        private void CreateChildrenRange(Panel panel, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            var property = obj.GetType().GetProperties();
            for (int i = 0; i < property.Length;)
            {
                var attr = property[i].GetCustomAttribute<UIMarkAttribute>();
                if (attr == null) { i++; continue; }
                panel.Children.Add(CreatePanelRange(property, ref i, property.Length, attr.LayerNumber, obj, obj_converter, bingd_converter, converter));
            }
        }

        private Grid CreatePanelRange(PropertyInfo[] properties, ref int index, int indexMax, int layer, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            Grid grid = new Grid();
            grid.Height = 40;
            ColumnDefinitionCollection columns = grid.ColumnDefinitions;
            int width = layer < 3 ? 100 : 50;
            for (int i = 0; i < layer; i++)
            {
                columns.Add(new ColumnDefinition()
                {
                    Width = new GridLength((layer == 3) && (i == 0) ? 80 : width),
                });
                columns.Add(new ColumnDefinition()
                {
                    Width = new GridLength(layer == 1 ? 300 : layer == 3 ? 80 : 100),
                });
            }
            return CreateContentRange(properties, 0, ref index, grid, indexMax, width, layer == 1 ? 300 : layer == 3 ? 80 : 100, layer, obj, obj_converter, bingd_converter, converter);
        }

        private Grid CreateContentRange(PropertyInfo[] properties, int column, ref int index, Grid grid, int indexMax, int blockWidth, int width, int layer,
            object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            if (layer == 0 || index >= indexMax) { return grid; }
            var attribute = properties[index].GetCustomAttribute<UIMarkAttribute>();
            if (attribute != null)
            {
                grid.Children.Add(GetTextBlockRange(attribute, column * 2, blockWidth));
                grid.Children.Add(GetContent(attribute, properties[index], column * 2 + 1, width, obj, obj_converter, bingd_converter, converter));
                layer -= 1;
                column++;
            }
            index++;
            return CreateContentRange(properties, column, ref index, grid, indexMax, blockWidth, width, layer, obj, obj_converter, bingd_converter, converter);
        }

        private TextBlock GetTextBlockRange(UIMarkAttribute attribute, int column, int width)
        {
            TextBlock textBlock = new TextBlock();
            textBlock.Text = attribute.Name;
            textBlock.HorizontalAlignment = HorizontalAlignment.Right;
            textBlock.VerticalAlignment = VerticalAlignment.Center;
            textBlock.SetValue(Grid.ColumnProperty, column);
            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            textBlock.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            if (!_displayItems.RoleInit.Any(x => x.RoleName == attribute.Name))
            {
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "范围",
                    Authority = Enums.AuthorityTypes.操作员,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "范围",
                    Authority = Enums.AuthorityTypes.工艺,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "范围",
                    Authority = Enums.AuthorityTypes.设备,
                    RoleName = attribute.Name,
                });
            }
            return textBlock;
        }
        #endregion

        #region 运行参数
        private void CreateMiscellaneousChildrenRange(Panel panel, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            var property = obj.GetType().GetProperties();
            for (int i = 0; i < property.Length;)
            {
                var attr = property[i].GetCustomAttribute<UIMarkAttribute>();
                if (attr == null) { i++; continue; }
                panel.Children.Add(CreateMiscellaneousPanelRange(property, ref i, property.Length, attr.LayerNumber, obj, obj_converter, bingd_converter, converter));
            }
        }

        private Grid CreateMiscellaneousPanelRange(PropertyInfo[] properties, ref int index, int indexMax, int layer, object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            Grid grid = new Grid();
            grid.Height = 40;
            ColumnDefinitionCollection columns = grid.ColumnDefinitions;
            int width = layer < 3 ? 100 : 50;
            for (int i = 0; i < layer; i++)
            {
                columns.Add(new ColumnDefinition()
                {
                    Width = new GridLength((layer == 3) && (i == 0) ? 80 : width),
                });
                columns.Add(new ColumnDefinition()
                {
                    Width = new GridLength(layer == 1 ? 300 : layer == 3 ? 80 : 100),
                });
            }
            return CreateMiscellaneousContentRange(properties, 0, ref index, grid, indexMax, width, layer == 1 ? 300 : layer == 3 ? 80 : 100, layer, obj, obj_converter, bingd_converter, converter);
        }

        private Grid CreateMiscellaneousContentRange(PropertyInfo[] properties, int column, ref int index, Grid grid, int indexMax, int blockWidth, int width, int layer,
            object obj, object obj_converter, string bingd_converter, IValueConverter converter)
        {
            if (layer == 0 || index >= indexMax) { return grid; }
            var attribute = properties[index].GetCustomAttribute<UIMarkAttribute>();
            if (attribute != null)
            {
                grid.Children.Add(GetMiscellaneousTextBlockRange(attribute, column * 2, blockWidth));
                grid.Children.Add(GetContent(attribute, properties[index], column * 2 + 1, width, obj, obj_converter, bingd_converter, converter));
                layer -= 1;
                column++;
            }
            index++;
            return CreateMiscellaneousContentRange(properties, column, ref index, grid, indexMax, blockWidth, width, layer, obj, obj_converter, bingd_converter, converter);
        }

        private TextBlock GetMiscellaneousTextBlockRange(UIMarkAttribute attribute, int column, int width)
        {
            TextBlock textBlock = new TextBlock();
            textBlock.Text = attribute.Name;
            textBlock.HorizontalAlignment = HorizontalAlignment.Right;
            textBlock.VerticalAlignment = VerticalAlignment.Center;
            textBlock.SetValue(Grid.ColumnProperty, column);
            var dynamicResource = new DynamicResourceExtension("MaterialDesignBody");
            var resourceReferenceExpression = dynamicResource.ProvideValue(null);
            textBlock.SetValue(Control.ForegroundProperty, resourceReferenceExpression);
            if (!_displayItems.RoleInit.Any(x => x.RoleName == attribute.Name))
            {
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "运行参数",
                    Authority = Enums.AuthorityTypes.操作员,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "运行参数",
                    Authority = Enums.AuthorityTypes.工艺,
                    RoleName = attribute.Name,
                });
                _displayItems.RoleInit.Add(new Models.RoleInitModel()
                {
                    IsEnable = true,
                    Category = "运行参数",
                    Authority = Enums.AuthorityTypes.设备,
                    RoleName = attribute.Name,
                });
            }
            return textBlock;
        }

        #endregion

        public DelegateCommand SaveParameter => new DelegateCommand(async () =>
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(Parameter.RunParameter.ContrastObject(RunParameter));
            stringBuilder.Append(Parameter.DecideParameter.ContrastObject(DecideParameter));
            stringBuilder.Append(Parameter.MESParameter.ContrastObject(MESParameter));
            stringBuilder.Append(Parameter.RangeParameter.ContrastObject(RangeParameter));
            stringBuilder.Append(Parameter.CollectionItemsParameter.ContrastObject(CollectionItemsParameter));
            string bl = "false";
            if (!string.IsNullOrEmpty(stringBuilder.ToString()))
            {
                bl = (string)await stringBuilder.ToString().MessageDialogs(MessageLevelType.警告, true, Enums.PopUpTypes.Global, Visibility.Visible);
            }
            else
            {
                return;
            }
            if (bl == "true")
            {
                RunParameter.UpdateValue(Parameter.RunParameter);
                RangeParameter.UpdateValue(Parameter.RangeParameter);
                MESParameter.UpdateValue(Parameter.MESParameter);
                DecideParameter.UpdateValue(Parameter.DecideParameter);
                CollectionItemsParameter.UpdateValue(Parameter.CollectionItemsParameter);
                if (!string.IsNullOrEmpty(stringBuilder.ToString()))
                {
                    $"用户：[{UserConfig.LoginUser.Name}] 修改 {stringBuilder.ToString()}".OperationLog(MessageLevelType.成功);
                }
            }
            else
            {
                Parameter.RunParameter.UpdateValue(RunParameter);
                Parameter.RangeParameter.UpdateValue(RangeParameter);
                Parameter.MESParameter.UpdateValue(MESParameter);
                Parameter.DecideParameter.UpdateValue(DecideParameter);
                Parameter.CollectionItemsParameter.UpdateValue(CollectionItemsParameter);
            }
            var serviceList = Temporary.LinkList.FirstOrDefault(x => x.ServiceName == "MES状态");
            if (serviceList != null) { serviceList.Status = Parameter.DecideParameter.EnableMES; }
            SetInjectionVolume();
            Parameter.Save();
        });

        public void Load()
        {
            Parameter.RunParameter.UpdateValue(RunParameter);
            Parameter.DecideParameter.UpdateValue(DecideParameter);
            Parameter.MESParameter.UpdateValue(MESParameter);
            Parameter.RangeParameter.UpdateValue(RangeParameter);
            Parameter.CollectionItemsParameter.UpdateValue(CollectionItemsParameter);
        }

        public void UnLoad()
        {

        }

        private void SetInjectionVolume()
        {
            //if (Parameter.DecideParameter.EnableVariableInjection)
            //{
            //    Temporary.InjectionVolume = Parameter.RangeParameter.Variables;
            //    Temporary.InjectionVolumeUP = Parameter.RangeParameter.VariablesUp;
            //    Temporary.InjectionVolumeLower = Parameter.RangeParameter.VariablesDown;
            //}
            //else
            //{
            Temporary.InjectionVolume = Parameter.RangeParameter.Quantitative;
            Temporary.InjectionVolumeUP = Parameter.RangeParameter.QuantitativeUp;
            Temporary.InjectionVolumeLower = Parameter.RangeParameter.QuantitativeDown;
            //}
        }

        private PasswordBox _passwordBox;
        private IMESInteraction _interaction;
        public DelegateCommand<PasswordBox> MESLogin => new DelegateCommand<PasswordBox>(async sender =>
        {
            try
            {
                if (_passwordBox == null)
                {
                    _passwordBox = sender;
                }
                _interaction = _interaction ?? new AccountInterface(DialogLogHelper.MesLog, DialogLogHelper.MESDialog);
                if (string.IsNullOrEmpty(Temporary.Mes_Account) || string.IsNullOrEmpty(_passwordBox.Password))
                {
                    _ = "请输入完整的账户名或密码！！！".MessageDialogs(MessageLevelType.警告, true, Enums.PopUpTypes.Global);
                    return;
                }
                _ = DialogHost.Show(new Views.Dialogs.LoadingDialogs(), PopUpTypes.Global.ToString()).ConfigureAwait(false);
                Dictionary<string, object> parameters = new Dictionary<string, object>()
            {
                {"parameter", new Dictionary<string, object>()
                  {
                    {"tenantID", Parameter.CollectionItemsParameter.ProductionLineNo },//产线编号
                    { "deviceCode", Parameter.CollectionItemsParameter.EquipNum },//设备编码
                    { "account", Temporary.Mes_Account.Trim() },//MES账户
                    { "password", MD5Encrypt.MD5Encrypt32( _passwordBox.Password.Trim())}//MES密码(经过MD5加密)                    
                  }
                },
                { "machineNo", Parameter.CollectionItemsParameter.EquipNum },//设备编码
                { "producttype", Parameter.CollectionItemsParameter.ProductType.ToString() },//生产类型
            };
                Temporary.Is_Mes_Login = await Task.Run(() => _interaction.Interaction(Parameter.MESParameter.BaseUrl + Parameter.MESParameter.AccountRoute,
                        Parameter.MESParameter.AccountTime,
                        Parameter.MESParameter.AccountNumber, DateTime.Now, null, parameters) == ResultTypes.合格);

                if (Temporary.Is_Mes_Login)
                {
                    var result = parameters["result"] as Dictionary<string, object>;
                    if (result != null)
                    {
                        Temporary.Mes_AccountDep = result.ContainsKey("accountDept") ? result["accountDept"]?.ToString() : "";
                        Temporary.Mes_Account = result.ContainsKey("account") ? result["account"]?.ToString() : "";
                        Temporary.Mes_AccountName = result.ContainsKey("accountName") ? result["accountName"]?.ToString() : "";
                        Temporary.Mes_AccountUser = result.ContainsKey("accountUser") ? result["accountUser"]?.ToString() : "";
                        Temporary.Mes_AccountTel = result.ContainsKey("accountTel") ? result["accountTel"]?.ToString() : "";
                    }
                    _ = "人员权限校验通过！！！".MessageDialogs(MessageLevelType.成功, true, PopUpTypes.Global);
                }
                if (!Temporary.Is_Mes_Login && DialogHost.IsDialogOpen(PopUpTypes.Global.ToString())) DialogHost.Close(PopUpTypes.Global.ToString());
            }
            catch (Exception ex)
            {

                _ = $"[登陆] 发生异常：{ex}".MessageDialogs(MessageLevelType.警告, true, PopUpTypes.Global);
            }

        });
        public DelegateCommand MESExit => new DelegateCommand(() =>
        {
            if (_passwordBox == null) { return; }
            _passwordBox.Password = default;
            Temporary.Mes_Account = default;
        });
        IMESInteraction getByProductCodeInterface;
        /// <summary>
        /// 获取工单
        /// </summary>
        public DelegateCommand GetProductCodeCMD => new DelegateCommand(() =>
        {
            getByProductCodeInterface = getByProductCodeInterface ?? new GetByProductCodeInterface(DialogLogHelper.MesLog, DialogLogHelper.MESDialog);
            DialogHost.Show(new ProductCodeDialog()
            {
                DataContext = new ProductCodeDialogViewModel(getByProductCodeInterface, Parameter, CollectionItemsParameter)
            }, PopUpTypes.Global.ToString()); ;
        });
        IMESInteraction materialInInterface;
        IMESInteraction materialOutInterface;
        IMESInteraction changeParamInterface;


    }
}
